package com.x.dao;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;

import com.x.model.Role;
import com.x.model.User;

@Component
public class UserDAO extends BaseDAO {

	public void saveUser(User user) {
		this.getSession().merge(user);
	}

	public User getUserByName(String username) {
		Criteria criteria = this.getSession().createCriteria(User.class);
		criteria.add(Restrictions.eq("username", username));
		criteria.setCacheable(true);
		return (User) criteria.uniqueResult();
	}

	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public Map<String, Object> list(int startIndex, int length,
			String searchValue, List<String> wherePart, List<String[]> odrerPart) {
		Criteria c = this.getSession().createCriteria(User.class);
		c.setCacheable(true);
		c.setProjection(Projections.rowCount());
		Object total = c.uniqueResult();

		for (String[] order : odrerPart) {
			if (order[1].equals("desc")) {
				c.addOrder(Order.desc(order[0]));
			} else {
				c.addOrder(Order.asc(order[0]));
			}
		}
		Disjunction disjunction = Restrictions.disjunction();
		if (StringUtils.isNotEmpty(searchValue)) {
			for (String columns : wherePart) {
				disjunction.add(Restrictions.or(Restrictions
						.sqlRestriction("{alias}." + columns + " LIKE '"
								+ searchValue + "%'")));
			}
		}
		c.add(disjunction);
		Object recordsFiltered = c.uniqueResult();
		c.setProjection(null);
		c.setFirstResult(startIndex);
		c.setMaxResults(length);
		List<User> users = c.list();
		List<String[]> dataResults = new ArrayList<>();
		for (User user : users) {
			synchronized (format) {
				String createTime = format.format(user.getCreatetime());
				List<Role> roleList = user.getRoles();
				if (roleList.size() > 0) {
					dataResults.add(new String[] { user.getId(),
							user.getUsername(), user.getNickname(), createTime,
							roleList.get(0).getRole() });
				} else {
					dataResults.add(new String[] { user.getId(),
							user.getUsername(), user.getNickname(), createTime,
							"" });
				}

			}

		}

		Map<String, Object> result = new HashMap<String, Object>();
		result.put("recordsTotal", total);
		result.put("recordsFiltered", recordsFiltered);
		result.put("data", dataResults);
		return result;
	}

	public User load(String id) {
		return (User) this.getSession().load(User.class, id);
	}

	public void delete(String id) {
		User user = (User) this.getSession().load(User.class, id);
		this.getSession().delete(user);

	}

	public String getRoleByName(String username) {
		Criteria criteria = this.getSession().createCriteria(User.class);
		criteria.add(Restrictions.eq("username", username));
		criteria.setCacheable(true);
		User user = (User) criteria.uniqueResult();
		return user.getRoles().get(0).getRole();
	}
}
